package com.ld.admin.controller.system.dbbackup;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.ld.admin.controller.AdminBasicController;
import com.ld.admin.model.system.codegen.CodegenDbsetModel;
import com.ld.admin.model.system.dbbackup.DbBackUpStatic;
import com.ld.admin.model.system.dbbackup.DbBackupManageModel;
import com.ld.admin.model.system.dbbackup.DbBackupSetModel;
import com.ld.admin.model.system.dbbackup.DbbackLogModel;
import com.ld.admin.model.system.dbbackup.DbbackUpInfoModel;
import com.ld.admin.service.codegen.CodegenService;
import com.ld.admin.service.system.dbbackup.BbBackUpFactory;
import com.ld.admin.service.system.dbbackup.DbBackUpService;
import com.ld.admin.service.system.dbbackup.queue.DBRecoveryThread;
import com.ld.admin.service.system.dbbackup.queue.DBbackupThread;
import com.ld.shieldsb.annotation.NoLog;
import com.ld.shieldsb.common.core.io.FileUtils;
import com.ld.shieldsb.common.core.model.Result;
import com.ld.shieldsb.common.core.util.StringUtils;
import com.ld.shieldsb.common.core.util.os.OSType;
import com.ld.shieldsb.common.core.util.os.OSUtil;
import com.ld.shieldsb.common.web.util.Web;
import com.ld.shieldsb.dao.model.QueryModel;
import com.ld.shieldsb.db.model.DBSetInfo;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

@Api(tags = "数据库备份")
@Controller
@RequestMapping("${shieldsb.adminPath}/system/dbbackup")
public class DBbackUpController extends AdminBasicController<DbbackUpInfoModel> {

    @Autowired
    public CodegenService codegenService;

    @Autowired
    public DbBackUpService dbBackUpService;

    /**
     * 
     * 
     * @Title main
     * @author 刘金浩
     * @date 2019年11月13日 下午1:41:37
     * @return String
     */
    @ApiOperation(value = "输出数据库选择页面", notes = "")
    @RequestMapping(path = "main", method = RequestMethod.GET)
    public String main() {
        return "a/system/dbbackup/dbbackup_main";
    }

    /**
     * 
     * 
     * @Title index
     * @author 刘金浩
     * @date 2019年11月13日 下午1:41:37
     * @return String
     */
    @ApiOperation(value = "输出数据库选择页面", notes = "")
    @RequestMapping(path = "", method = RequestMethod.GET)
    public String index() {
        return "forward:" + adminPath + "/system/dbbackup/main"; // 跳转搜索页面
    }

    @ApiOperation(value = "到搜索页面", notes = "")
    @RequestMapping(path = "/toSearch", method = RequestMethod.GET)
    public String toSearch() throws ServletException, IOException {
        // 搜索数据库设置
        List<CodegenDbsetModel> dbSetList = basicService.getList(CodegenDbsetModel.class, basicService.getNormalQueryModel());
        request.setAttribute("dbsets", dbSetList);
        return "a/system/dbbackup/backup/dbbackupSearch";
    }

    @ApiOperation(value = "搜索表主要信息", notes = "")
    @RequestMapping(path = "/search", method = RequestMethod.POST)
    public String search() throws ServletException, IOException {
        setAttributes();
        QueryModel queryModel = dbBackUpService.getSearchQueryModel(request);
        dbBackUpService.getPageBean(request, getModelClass(), queryModel);
        return "a/system/dbbackup/backup/dbbackupList";
    }

    @ApiOperation(value = "备份数据", notes = "")
    @RequestMapping(path = "/quickBackup", method = RequestMethod.POST)
    @ResponseBody
    public void quickBackup() throws ServletException, IOException {
        Long dbConnId = getLong("dbConnId");
        DbBackupSetModel backupModel = new DbBackupSetModel();
        backupModel.setDbConnId(dbConnId);
        backupModel.setBackupType(DbBackUpStatic.DBBACKUP.BACKUPTYPE_DATABASE);
        backupModel.setDbHandler(DbBackUpStatic.DBBACKUP.DBHANDLER_ALL);
        BbBackUpFactory.backupDb(backupModel);
    }

    @ApiOperation(value = "备份数据", notes = "")
    @RequestMapping(path = "/backupSystem", method = RequestMethod.POST)
    @ResponseBody
    public Result backupSystem(DbBackupSetModel backupModel) throws ServletException, IOException {
        BbBackUpFactory.backupDb(backupModel);
        return Web.Response.success("");
    }

    @ApiOperation(value = "还原数据", notes = "")
    @RequestMapping(path = "/torecovery", method = RequestMethod.GET)
    public String torecovery() throws ServletException, IOException {
        setAttributes();
        // 搜索数据库设置
        List<CodegenDbsetModel> dbSetList = basicService.getList(CodegenDbsetModel.class, basicService.getNormalQueryModel());
        request.setAttribute("dbsets", dbSetList);
        return "a/system/dbbackup/backup/dbbackupRecovery";
    }

    @ApiOperation(value = "还原数据", notes = "")
    @RequestMapping(path = "/recovery", method = RequestMethod.POST)
    @ResponseBody
    public Result recovery(DbBackupSetModel backupModel) throws ServletException, IOException {
        DBSetInfo dbSetInfo = codegenService.getDbSetInfo(getLong("dbConnId"));
        DbbackUpInfoModel backUpInfoModel = dbBackUpService.getOne(DbbackUpInfoModel.class, getLong("id"));
        if (backUpInfoModel != null && dbSetInfo != null) {
            dbBackUpService.mysqlRecovery(dbSetInfo, backUpInfoModel);
        } else {
            return Web.Response.error("备份还原失败");
        }
        return Web.Response.success("");
    }

    @ApiOperation(value = "进度页面", notes = "")
    @RequestMapping(path = "/process", method = RequestMethod.GET)
    public String process() throws ServletException, IOException {
        setAttributes();
        return "a/system/dbbackup/backup/dbprocess";
    }

    @ApiOperation(value = "获取进度", notes = "")
    @RequestMapping(path = "/getProcess", method = RequestMethod.POST)
    @NoLog
    @ResponseBody
    public Result getProcess() throws ServletException, IOException {

        int type = getInt("type");

        Result result = new Result();
        DbbackLogModel model = null;
        if (type == 0) {
            model = DBbackupThread.getDbbackLogModel();
        } else {
            model = DBRecoveryThread.getDbbackLogModel();
        }
        result.setSuccess(true);
        result.setData(model);
        return result;
    }

    @ApiOperation(value = "判断备份文件是否存在", notes = "")
    @RequestMapping("isExitDownFile")
    @ResponseBody
    public Object isExitDownFile() throws ServletException, IOException {
        return dbBackUpService.isExitDownFile();
    }

    /**
     * 附件下载
     */
    @ApiOperation(value = "备份文件下载", notes = "")
    @RequestMapping("downloadAtt")
    @ResponseBody
    public void downloadAtt() throws ServletException, IOException {
        dbBackUpService.downloadAtt();
    }

    @ApiOperation(value = "删除备份文件", notes = "")
    @RequestMapping("del")
    @ResponseBody
    public Object del() throws ServletException, IOException {
        long id = getLong("id");
        DbbackUpInfoModel model = basicService.getOne(getModelClass(), id);
        Result result = basicService.remove(getModelClass(), id);
        if (result.getSuccess()) {
            if (FileUtils.exists(model.getBackupFilePath())) {
                FileUtils.delete(model.getBackupFilePath());
            }
        }
        return result;
    }

    @ApiOperation(value = "数据库备份设置", notes = "")
    @RequestMapping(path = "/toDbbackupSet", method = RequestMethod.GET)
    public String toDbbackupSet() throws ServletException, IOException {
        // 搜索数据库设置
        List<CodegenDbsetModel> dbSetList = basicService.getList(CodegenDbsetModel.class, basicService.getNormalQueryModel());
        request.setAttribute("dbsets", dbSetList);
        return "a/system/dbbackup/set/dbbackupSet";
    }

    @ApiOperation(value = "数据库备份参数设置", notes = "")
    @RequestMapping(path = "/dbbackupManage", method = RequestMethod.GET)
    public String dbbackupManage() throws ServletException, IOException {
        // 搜索数据库设置
        OSType osType = OSUtil.getOSType();
        setAttribute("osType", osType.toString());
        QueryModel qureyModel = basicService.getNormalQueryModel();
        basicService.getOne(request, DbBackupManageModel.class, qureyModel);
        return "a/system/dbbackup/set/dbbackupManage";
    }

    @ApiOperation(value = "数据库备份配置管理", notes = "")
    @RequestMapping(path = "/backupManageAddorUpdate", method = RequestMethod.POST)
    @ResponseBody
    public Object backupManageAddorUpdate(DbBackupManageModel model) throws ServletException, IOException {
        return basicService.addOrUpdate(model, model.getId() != null);
    }

    @ApiOperation(value = "文件夹选择", notes = "")
    @RequestMapping(path = "/toFileTree", method = RequestMethod.GET)
    public String toFileTree() throws ServletException, IOException {
        return "a/system/dbbackup/set/fileTree";
    }

    @ApiOperation(value = "展开文件树", notes = "")
    @RequestMapping(path = "/expandfileTree")
    // 返回json格式
    @ResponseBody
    public Object expandfileTree(String... args) throws ServletException, IOException {
        // 返回磁盘驱动器根目录
        Result result = new Result();
        List<Map<String, Object>> fileMapList = new ArrayList<>();
        if (StringUtils.isEmpty(getString("id"))) {

            File[] roots = File.listRoots();
            for (File r : roots) {
                Map<String, Object> dataMap = new LinkedHashMap<>();
                dataMap.put("id", r.getAbsolutePath());
                dataMap.put("name", r.getPath());
                if (hasDirs(r)) {
                    dataMap.put("isParent", true);
                    dataMap.put("open", false);
                } else {
                    dataMap.put("isParent", false);
                    dataMap.put("open", true);
                }
                fileMapList.add(dataMap);
            }
            result.setSuccess(true);
            result.setData(fileMapList);
            return result;
        } else {
            // 返回子目录集

            List<File> dirList = FileUtils.getAllDirectory(getString("id"));
            dirList.forEach(r -> {
                Map<String, Object> dataMap = new LinkedHashMap<>();
                dataMap.put("pId", getString("id"));
                dataMap.put("id", r.getAbsolutePath());
                dataMap.put("name", r.getPath());
                if (hasDirs(r)) {
                    dataMap.put("isParent", true);
                    dataMap.put("open", false);
                } else {
                    dataMap.put("isParent", false);
                    dataMap.put("open", true);
                }
                fileMapList.add(dataMap);
            });

            return fileMapList;
        }

    }

    private boolean hasDirs(File dir) {
        try {
            if (dir.listFiles().length == 0) {
                return false;
            } else {
                return true;
            }
        } catch (Exception e) {
            return false;
        }
    }
}
